package com.zoe.app.completeFuture_入门;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.zoe.app.util.SmallTool;
import org.junit.Test;

import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Supplier;

/**
 * @author zoe.Zhang
 * @date 2022/07/21
 * @description
 */
public class A_CompleteFuture {

    public static void main(String[] args) {

    }

    @Test
    public void T1() {

        //   |
        //   |
        //   |      |
        //   |      |
        //   |      |
        //   |
        SmallTool.printTimeAndThread("小明进入饭店...");
        SmallTool.printTimeAndThread("小明点了 番茄炒蛋+蛋炒饭");

        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("厨师炒菜...");
            ThreadUtil.sleep(200);
            SmallTool.printTimeAndThread("厨师盛饭...");
            ThreadUtil.sleep(100); // 线程睡眠 0.5 秒
            return "饭已ok+下来咪西";
        });

        SmallTool.printTimeAndThread("小明开了王者荣耀...");
        // join() 获取CompletableFuture的返回值，并且返回值的类型和CompletableFuture的泛型是一致的
        String join = completableFuture.join();
        SmallTool.printTimeAndThread(StrUtil.format("{},小明开始吃饭...", join));
    }

    /**
     * thenCompose
     * 参考 axios()
     * .then()
     * .then()
     *
     * thenCompose和thenApply异同
     * https://www.jianshu.com/p/0e9aeb38dddf?u_atoken=55e03806-a556-4fc8-b638-1d4f50dadab9&u_asession=01hh-Y3j1OtWMeWctuSzaRJCHoidhwdbbyRW4fJlwZLNvwLl5fYRvZEmc3d5GgBmtNX0KNBwm7Lovlpxjd_P_q4JsKWYrT3W_NKPr8w6oU7K8qX1hi5esSZTCe6gWnQU_MK1h9zIJGqUc2hCV04v6XLWBkFo3NEHBv0PZUm6pbxQU&u_asig=05e8UfzbqaZ0I2SYhoWmA47xSFXMRcytcyIwbVSi7jEQLWg758hGA0XLSPoBuxs5XlYOtqoOYH_DqKIFK3JdzbDn5ew15Qfe0A7P4pd-BFIfbSiTSQ0aZR8a9jTH6w8sojjLbdfuPxIJG2mzSmbrAsO7fDdvtNi8Xbmx5sVBTftU_9JS7q8ZD7Xtz2Ly-b0kmuyAKRFSVJkkdwVUnyHAIJzXaXdYaBa28xhKtWWl7FiJZAj_zrdxT74xjFte9c4_qLn3URtWYq5VQe2s5Xl6Zn2u3h9VXwMyh6PgyDIVSG1W-U1wsfZHRS8xvsMyxNQ_Dp3yLY6mZgdXquFtyGe0Dheow67T-FtabVGS8cTPQ2-Rgq7Qv_ZgRJTEV0XAfU9l_6mWspDxyAEEo4kbsryBKb9Q&u_aref=6wFp%2FEdmXvTasYgaINEqAQJCctI%3D
     */
    @Test
    public void T2() {
        SmallTool.printTimeAndThread("小明进入饭店...");
        SmallTool.printTimeAndThread("小明点了 番茄炒蛋+蛋炒饭");

        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("厨师炒菜...");
            ThreadUtil.sleep(0.2 * 1000); // 线程睡眠 0.2 秒
            return "番茄炒蛋";
        })
                                                                             .thenCompose(res -> CompletableFuture.supplyAsync(() -> {
                                                                                 SmallTool.printTimeAndThread("服务员开始打饭...");
                                                                                 ThreadUtil.sleep(0.1 * 1000); // 线程睡眠 0.1 秒
                                                                                 return res + "米饭";
                                                                             }));

        SmallTool.printTimeAndThread("小明开了王者荣耀...");
        // join() 获取CompletableFuture的返回值，并且返回值的类型和CompletableFuture的泛型是一致的
        SmallTool.printTimeAndThread(StrUtil.format("{},小明开始吃饭...", stringCompletableFuture.join()));
    }

    /**
     * thenCombine
     * Combine = 合并
     * 参考 axios.all
     */
    @Test
    public void T3() {

        SmallTool.printTimeAndThread("小明进入饭店...");
        SmallTool.printTimeAndThread("小明点了 番茄炒蛋+蛋炒饭");

        Supplier<String> stringSupplier = () -> {
            SmallTool.printTimeAndThread("厨师开始炒菜..");
            return "菜炒好了...";
        };
        CompletableFuture<String> other = CompletableFuture.supplyAsync(() -> {
            SmallTool.printTimeAndThread("服务员开始煮饭...");
            return "饭已经煮好了...";
        });
        BiFunction<String, String, String> stringStringStringBiFunction = (res1, res2) -> res1 + res1;

        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(stringSupplier)
                                                                             .thenCombine(other, stringStringStringBiFunction);
        SmallTool.printTimeAndThread("小明开始打王者...");
        String join = stringCompletableFuture.join();
        SmallTool.printTimeAndThread(StrUtil.format("{},小吃开始", join));
    }
}
